/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package AccManager;

/* Standard import */
import java.io.*;
import java.util.*;

/**
 *
 * @author lcy
 */
public class ServerAccManager extends AccManager {

    private ServerSAXParser server_db_parser;
    private ServerDOMGenerator _serv_db_generator;
    private List<UserProfile> temp_user_list;
    private static final int INIT_TIME_TO_LIVE = 10; //60 sec

    //Constructor
    public ServerAccManager(){
        server_db_parser = new ServerSAXParser();
        _serv_db_generator = new ServerDOMGenerator();
        InitCommonComponents();
    }

    public ServerAccManager(String file_name){
         server_db_parser = new ServerSAXParser(file_name);
         _serv_db_generator = new ServerDOMGenerator(null, file_name);
         InitCommonComponents();
    }

    private void InitCommonComponents(){
         
    }

    public void ParseCurDataBase(){
         temp_user_list = server_db_parser.parseDocument();
    }

    public void NewEmptyDBFile(){
        
        _serv_db_generator.createDocument(temp_user_list);
        
        
    }

    public void InitImport(){
        _serv_db_generator.createDOMTree();
    }

    public void AddNewUser(UserProfile new_user){

        new_user.SetTimeToLive(INIT_TIME_TO_LIVE);
        new_user.SetUserStatus(UserStatus.ONLINE);
        _serv_db_generator.AddNewEntry(new_user);
        _serv_db_generator.AddNewEntryDOM(new_user);
    }

    public List<UserProfile> GetUserListRef(){
        return temp_user_list;
    }

    public void FillInDBFile(){
        _serv_db_generator.printToFile();
        _debugger.LogInfo("Server Acc manager: DOM file is written");
    }

    public boolean IsNewUserValid(UserProfile new_user){

        if(FindUser(new_user) != -1)
            return false;
        
        return true;
    }

    public int FindUser(UserProfile new_user){

        String new_name = new_user.GetUserID();

        for(int idx = 0 ; idx < temp_user_list.size();idx ++){
            String cur_user_name = (temp_user_list.get(idx)).GetUserID();
            
            if(new_name.compareTo(cur_user_name) == 0){
               return idx;
            }
        }

        return -1; //i.e. not found
    }

    //pre: idx is valid
    public UserProfile getUserProfile(int idx){
           return temp_user_list.get(idx);
    }

    public boolean UserLoginAuthentication(int idx, UserProfile user){
        
        UserProfile db_entry = temp_user_list.get(idx);
        if(db_entry.GetPasswdRaw().compareTo(user.GetPasswdRaw()) == 0){
            db_entry.SetUserStatus(UserStatus.ONLINE);
            db_entry.SetUserIP(user.GetUserIP());
            db_entry.SetUserPort(user.GetUserPort());
            db_entry.SetTimeToLive(INIT_TIME_TO_LIVE);
            return true;
        }
        else
            return false;
    }

    public UserStatus IsUserOnline(UserProfile profile){
        int idx = 0;
        
        if((idx = FindUser(profile)) < 0)
            return UserStatus.NONEXIST;

        UserProfile the_user = temp_user_list.get(idx);

        return the_user.GetUserStatus();
    }

    public synchronized void DecrementTTL(){
        for(int idx = 0 ; idx < temp_user_list.size();idx ++){
            UserProfile cur_player = (temp_user_list.get(idx));
            UserStatus user_status = cur_player.GetUserStatus();
            if( user_status == UserStatus.ONLINE || user_status == UserStatus.INGAME ){
               cur_player.DecrementTTL();
               if(cur_player.IsTimeOut())
               {
                   cur_player.SetUserStatus(UserStatus.OFFLINE);
                   _debugger.LogInfo("ServerAccManager:Player " + cur_player.GetUserID() +" time out");
               }
            }
        }
    }

    public synchronized void UpdateUserProfile(UserProfile profile){
            int idx = FindUser(profile);
            
            if(idx > -1){
                UserProfile ref = getUserProfile(idx);
                ref.copy(profile);
            }
    }

    public synchronized void ResetTTL(String user_name){
        UserProfile arg = new UserProfile(user_name,"");

        int idx = this.FindUser(arg);

        if(idx >= 0){
            UserProfile cur_player = (temp_user_list.get(idx));
            UserStatus user_status = cur_player.GetUserStatus();
            if( user_status == UserStatus.ONLINE || user_status == UserStatus.INGAME ){
               cur_player.SetTimeToLive(INIT_TIME_TO_LIVE);

            }else if (user_status == UserStatus.OFFLINE){

            }
        }
        
    }
}
